# -*- coding: utf-8 -*-

"""
Moduł odpowiedzialny za przeprowadzanie operacji na punktach.

B{Moduł zawiera:}
    1. Klasa Point
        - Metoda __init__
        - Metoda getPositionX
        - Metoda getPositionY
        - Metoda setPositionX
        - Metoda setPositionY
        - Metoda getDistanceToPoint
        - Metoda getDistanceToLine
        - Metoda substractPoint
        - Metoda moveByVector
        - Metoda moveAgainstVector
"""

from __future__ import unicode_literals
from math import sqrt, fabs
from Vectors import Vector



class Point(object):
    """
    Klasa reprezentująca obiekt punktu w układzie współrzędnych.
    """
    
    
    def __init__(self, positionX, positionY):
        """
        Konstruktor tworzy obiekt punktu o podanych współrzędnych.
        
        @param positionX: Parametr określający współrzędną punktu na osi X.
        @param positionY: Parametr określający współrzędną punktu na osi Y.
        """
        
        self._PositionX = positionX
        self._PositionY = positionY
    
    
    def getPositionX(self):
        """
        Funkcja zwracająca położenie X punktu.
        
        @return: Współrzędną punktu na osi X.
        """
        
        return self._PositionX
    
    
    def getPositionY(self):
        """
        Funkcja zwracająca położenie Y punktu.
        
        @return: Współrzędną punktu na osi Y.
        """
        
        return self._PositionY
    
    
    def setPositionX(self, positionX):
        """
        Funkcja ustawiająca położenie X punktu.
        
        @param positionX: Parametr określający współrzędną punktu na osi X.
        """
        
        self._PositionX = positionX
    
    
    def setPositionY(self, positionY):
        """
        Funkcja ustawiająca położenie Y punktu.
        
        @param positionY: Parametr określający współrzędną punktu na osi Y.
        """
        
        self._PositionY = positionY
    
    
    def getDistanceToPoint(self, point):
        """
        Funkcja zwracająca odległość między punktami.
        
        @param point: Parametr określający współrzędne punktu.
        
        @return: Odległość między punktami:
            M{sqrt((X2-X1)^2 + (Y2-Y1)^2)}
        """
        
        return sqrt((self.getPositionX()-point.getPositionX())**2 + (self.getPositionY()-point.getPositionY())**2)
    
    
    def getDistanceToLine(self, point1, point2):
        """
        Funkcja zwracająca najmniejszą odległość między punktem, a prostą
        przechodząca przez dwa podane w parametrach punkty.
        
        Uwaga! Funkcja zwraca odległość równą długości lewego wektora 
        normalnego pomnożonego przez odległość punktu od prostej, zbudowanego
        z wektora (point1, point2). Jeśli odległość ta powinna być zbudowana
        na prawym wektorze normalnym, to jej wartość będzie ujemna. Aby temu
        zapobiec można zmienić kolejność podawanych w parametrach punktów.
        
        @param point1: Parametr określający punkt będący początkiem lini.
        @param point2: Parametr określający punkt będący końcem lini.
        
        @return: Odległość punktu od prostej.
        """
        
        # wektor jednostkowy z punktu1 do punktu2
        ab = Vector(point2.getPositionX()-point1.getPositionX(), point2.getPositionY()-point1.getPositionY())
        ab.multiplyVector(1/ab.getVectorLength())
        
        # wektor normalny do wektora p1p2
        n = Vector(-ab.getVy(), ab.getVx())
        
        # wektor od punktu a do c (c = self)
        ac = Vector(self.getPositionX()-point1.getPositionX(), self.getPositionY()-point1.getPositionY())
        
        return ac.getVx()*n.getVx() + ac.getVy()*n.getVy()
    
    
    def substractPoint(self, anotherPoint):
        """
        Funkcja obliczająca wektor będący różnicą punktu, na rzecz którego
        została wywołana i punktu przekazanego w parametrze.
        
        @param anotherPoint: Parametr określający punkt, o którego współrzędne
        należy pomniejszyć współrzędne bieżącego punktu.
        
        @return: Wektor będący różnicą punktów.
        """
        
        return Vector(self.getPositionX()-anotherPoint.getPositionX(), self.getPositionY()-anotherPoint.getPositionY())
    
    
    def moveByVector(self, vector):
        """
        Procedura przesuwająca punkt o podany w parametrze wektor w kierunku zgodnym.
        
        @param vector: Parametr określający składowe wektora na osiach X i Y.
        """
        
        self.setPositionX(self.getPositionX() + vector.getVx())
        self.setPositionY(self.getPositionY() + vector.getVy())
    
    
    def moveAgainstVector(self, vector):
        """
        Procedura przesuwająca punkt o podany w parametrze wektor w kierunku przeciwnym.
        
        @param vector: Parametr określający składowe wektora na osiach X i Y.
        """
        
        self.setPositionX(self.getPositionX() - vector.getVx())
        self.setPositionY(self.getPositionY() - vector.getVy())